/*
MIT License

Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo/loom
*/

#ifndef simodo_interpret_host_fuze_SemanticsHost_abstract
#define simodo_interpret_host_fuze_SemanticsHost_abstract

/*! \file SemanticsHost_abstract.h
    \brief Класс разбора SBL операции, заданной в виде ноды семантического дерева (StNode)
*/

#include "simodo/interpret/Interpret.h"
// #include "simodo/interpret/SemanticModule_interface.h"
#include "simodo/parser/fuze/FuzeOperationCode.h"
#include "simodo/parser/Grammar.h"


namespace simodo::interpret::builtins
{
    enum class ProductionForWhat
    {
        Adding,
        Removing,
    };

    class FuzeInterpret_abstract;

    typedef InterpretState (*OperationParser_t) (FuzeInterpret_abstract &, const simodo::ast::Node &);

    class FuzeInterpret_abstract: public SemanticModule_interface
    {
        Interpret_interface *       _interpret;
        std::string                 _grammar_name;  ///< Наименование грамматики
        parser::Grammar &           _grammar;
        parser::TableBuildMethod    _method;
        bool                        _need_strict_rule_consistency;

        std::vector<parser::GrammarRuleTokens>  
                                    _rules;
        inout::Token                _main_rule;

    public:
        FuzeInterpret_abstract() = delete;
        FuzeInterpret_abstract(Interpret_interface * inter, 
                               std::string grammar_name,
                               parser::Grammar & grammar,
                               parser::TableBuildMethod method=parser::TableBuildMethod::none,
                               bool need_strict_rule_consistency=true);

    // Гетеры

    public:
        Interpret_interface &       inter()                               { return *_interpret; }
        const std::string &         grammar_name()                  const { return _grammar_name; }
        const parser::Grammar &     grammar()                       const { return _grammar; }
        parser::TableBuildMethod    method()                        const { return _method; }
        bool                        need_strict_rule_consistency()  const { return _need_strict_rule_consistency; }
        const std::vector<parser::GrammarRuleTokens> & rules()      const { return _rules; }
        const inout::Token &        main_rule()                     const { return _main_rule; }

    // Наследие SemanticModule_interface

    public:
        virtual void    setInterpret(Interpret_interface * inter)       override { _interpret = inter; }
        virtual void    reset()                                         override;
        virtual InterpretState   before_start()                         override { return InterpretState::Flow; }
        virtual bool    isOperationExists(simodo::ast::OperationCode operation_code) const override;
        virtual InterpretState   performOperation(const simodo::ast::Node & op)  override;
        virtual bool    checkSemanticName(const std::u16string & semantic_name) const override 
                                { return semantic_name == parser::FUZE_HOST_NAME; }
        virtual InterpretState   before_finish(InterpretState state)    override;

    // Группа методов, выполняющих разбор структуры СД конкретной операции

    public:
        InterpretState parseMain(const simodo::ast::Node & op);
        InterpretState parseGlobalScript(const simodo::ast::Node & op);
        InterpretState parseProduction(const simodo::ast::Node & op, ProductionForWhat what=ProductionForWhat::Adding);
        InterpretState parseRef(const simodo::ast::Node & op);

    // Группа методов непосредственно отвечающих за выполнение уже разобранной и подготовленной операции.
    // Различные типы интерпретаторов могут перехватывать (перегружать) эти методы для выполнения 
    // специальных действий.

    public:
        virtual InterpretState   executeMain         (const inout::Token & main_production);
        virtual InterpretState   executeGlobalScript (const inout::Token & label, const simodo::ast::Node & script);
        virtual InterpretState   executeProduction   (const inout::Token & production, 
                                             const std::vector<inout::Token> & pattern, 
                                             const inout::Token & direction_token,
                                             const simodo::ast::Node & action);
        virtual InterpretState   executeRemovingProduction(const inout::Token & production, 
                                             const std::vector<inout::Token> & pattern,
                                             const simodo::ast::Node & action);
        virtual InterpretState   executeRef          (const inout::Token & token, const std::u16string & ref);
        virtual InterpretState   executeFinal        (InterpretState state);

    private:
        size_t findRule(const std::vector<parser::GrammarRuleTokens> & rules, 
                        const inout::Token & production, const std::vector<inout::Token> & pattern);
    };
}

#endif // simodo_interpret_host_fuze_SemanticsHost_abstract
